﻿using System;
using System.Collections.Generic;

namespace Mono.Cecil
{
	// Token: 0x020000A0 RID: 160
	internal sealed class MethodReferenceComparer : EqualityComparer<MethodReference>
	{
		// Token: 0x06000651 RID: 1617 RVA: 0x00020C64 File Offset: 0x0001EE64
		public override bool Equals(MethodReference x, MethodReference y)
		{
			return MethodReferenceComparer.AreEqual(x, y);
		}

		// Token: 0x06000652 RID: 1618 RVA: 0x00020C80 File Offset: 0x0001EE80
		public override int GetHashCode(MethodReference obj)
		{
			return MethodReferenceComparer.GetHashCodeFor(obj);
		}

		// Token: 0x06000653 RID: 1619 RVA: 0x00020C98 File Offset: 0x0001EE98
		public static bool AreEqual(MethodReference x, MethodReference y)
		{
			bool flag = x == y;
			bool result;
			if (flag)
			{
				result = true;
			}
			else
			{
				bool flag2 = x.HasThis != y.HasThis;
				if (flag2)
				{
					result = false;
				}
				else
				{
					bool flag3 = x.HasParameters != y.HasParameters;
					if (flag3)
					{
						result = false;
					}
					else
					{
						bool flag4 = x.HasGenericParameters != y.HasGenericParameters;
						if (flag4)
						{
							result = false;
						}
						else
						{
							bool flag5 = x.Parameters.Count != y.Parameters.Count;
							if (flag5)
							{
								result = false;
							}
							else
							{
								bool flag6 = x.Name != y.Name;
								if (flag6)
								{
									result = false;
								}
								else
								{
									bool flag7 = !TypeReferenceEqualityComparer.AreEqual(x.DeclaringType, y.DeclaringType, TypeComparisonMode.Exact);
									if (flag7)
									{
										result = false;
									}
									else
									{
										GenericInstanceMethod genericInstanceMethod = x as GenericInstanceMethod;
										GenericInstanceMethod genericInstanceMethod2 = y as GenericInstanceMethod;
										bool flag8 = genericInstanceMethod != null || genericInstanceMethod2 != null;
										if (flag8)
										{
											bool flag9 = genericInstanceMethod == null || genericInstanceMethod2 == null;
											if (flag9)
											{
												return false;
											}
											bool flag10 = genericInstanceMethod.GenericArguments.Count != genericInstanceMethod2.GenericArguments.Count;
											if (flag10)
											{
												return false;
											}
											for (int i = 0; i < genericInstanceMethod.GenericArguments.Count; i++)
											{
												bool flag11 = !TypeReferenceEqualityComparer.AreEqual(genericInstanceMethod.GenericArguments[i], genericInstanceMethod2.GenericArguments[i], TypeComparisonMode.Exact);
												if (flag11)
												{
													return false;
												}
											}
										}
										MethodDefinition methodDefinition = x.Resolve();
										MethodDefinition methodDefinition2 = y.Resolve();
										bool flag12 = methodDefinition != methodDefinition2;
										if (flag12)
										{
											result = false;
										}
										else
										{
											bool flag13 = methodDefinition == null;
											if (flag13)
											{
												bool flag14 = MethodReferenceComparer.xComparisonStack == null;
												if (flag14)
												{
													MethodReferenceComparer.xComparisonStack = new List<MethodReference>();
												}
												bool flag15 = MethodReferenceComparer.yComparisonStack == null;
												if (flag15)
												{
													MethodReferenceComparer.yComparisonStack = new List<MethodReference>();
												}
												for (int j = 0; j < MethodReferenceComparer.xComparisonStack.Count; j++)
												{
													bool flag16 = MethodReferenceComparer.xComparisonStack[j] == x && MethodReferenceComparer.yComparisonStack[j] == y;
													if (flag16)
													{
														return true;
													}
												}
												MethodReferenceComparer.xComparisonStack.Add(x);
												try
												{
													MethodReferenceComparer.yComparisonStack.Add(y);
													try
													{
														for (int k = 0; k < x.Parameters.Count; k++)
														{
															bool flag17 = !TypeReferenceEqualityComparer.AreEqual(x.Parameters[k].ParameterType, y.Parameters[k].ParameterType, TypeComparisonMode.Exact);
															if (flag17)
															{
																return false;
															}
														}
													}
													finally
													{
														MethodReferenceComparer.yComparisonStack.RemoveAt(MethodReferenceComparer.yComparisonStack.Count - 1);
													}
												}
												finally
												{
													MethodReferenceComparer.xComparisonStack.RemoveAt(MethodReferenceComparer.xComparisonStack.Count - 1);
												}
											}
											result = true;
										}
									}
								}
							}
						}
					}
				}
			}
			return result;
		}

		// Token: 0x06000654 RID: 1620 RVA: 0x00020FB8 File Offset: 0x0001F1B8
		public static bool AreSignaturesEqual(MethodReference x, MethodReference y, TypeComparisonMode comparisonMode = TypeComparisonMode.Exact)
		{
			bool flag = x.HasThis != y.HasThis;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				bool flag2 = x.Parameters.Count != y.Parameters.Count;
				if (flag2)
				{
					result = false;
				}
				else
				{
					bool flag3 = x.GenericParameters.Count != y.GenericParameters.Count;
					if (flag3)
					{
						result = false;
					}
					else
					{
						for (int i = 0; i < x.Parameters.Count; i++)
						{
							bool flag4 = !TypeReferenceEqualityComparer.AreEqual(x.Parameters[i].ParameterType, y.Parameters[i].ParameterType, comparisonMode);
							if (flag4)
							{
								return false;
							}
						}
						bool flag5 = !TypeReferenceEqualityComparer.AreEqual(x.ReturnType, y.ReturnType, comparisonMode);
						result = !flag5;
					}
				}
			}
			return result;
		}

		// Token: 0x06000655 RID: 1621 RVA: 0x000210A8 File Offset: 0x0001F2A8
		public static int GetHashCodeFor(MethodReference obj)
		{
			GenericInstanceMethod genericInstanceMethod = obj as GenericInstanceMethod;
			bool flag = genericInstanceMethod != null;
			int result;
			if (flag)
			{
				int num = MethodReferenceComparer.GetHashCodeFor(genericInstanceMethod.ElementMethod);
				for (int i = 0; i < genericInstanceMethod.GenericArguments.Count; i++)
				{
					num = num * 486187739 + TypeReferenceEqualityComparer.GetHashCodeFor(genericInstanceMethod.GenericArguments[i]);
				}
				result = num;
			}
			else
			{
				result = TypeReferenceEqualityComparer.GetHashCodeFor(obj.DeclaringType) * 486187739 + obj.Name.GetHashCode();
			}
			return result;
		}

		// Token: 0x040001CD RID: 461
		[ThreadStatic]
		private static List<MethodReference> xComparisonStack;

		// Token: 0x040001CE RID: 462
		[ThreadStatic]
		private static List<MethodReference> yComparisonStack;
	}
}
